<template>
  <div class="search-container" style="width: calc(100vw); height: calc(100vh);" @contextmenu="onContextMenu">
    <MonacoEditor  v-if="type === 'text'" class="w-full h-40" v-model="searchText" :disabled="disabled" :constModelData="constModelData" :eheight="eheight" style="width: calc(100vw);" :editorConfig="editorConfig" :minimap="true"></MonacoEditor>
    <VditorEditor v-model:modelValue="searchText" v-if="type === 'md'"></VditorEditor>
    <MonacoDiff  v-if="type === 'diff'" class="w-full h-40" :original="searchText" :modified="searchText2" language="json" :theme="theme" >
    </MonacoDiff>
  </div>
</template>

<style scoped>
html, body {
  background-color: #1e1e1e; /* 或 transparent / black，根据你的 UI */
  margin: 0;
  padding: 0;
}

</style>

<script setup lang="ts">
    import { h, nextTick, onMounted, ref, watch } from 'vue'
    import { NButton, NInput, useDialog, useMessage } from 'naive-ui'
    import { getCurrentWindow } from '@tauri-apps/api/window';
    import { invoke } from '@tauri-apps/api/core';
    import MonacoEditor from '../components/monaco/index.vue'
    import MonacoDiff from '../components/monaco/MonacoDiff.vue'
    import VditorEditor from '../components/vditor/index.vue'
    import { useKeyboard } from '../components/useKeyboard';

    import prettier from 'prettier/standalone'
    import pluginBabel    from 'prettier/plugins/babel'    // JS/TS/JSON
    import pluginEstree   from 'prettier/plugins/estree'   // 必需：estree 支持
    import pluginHtml     from 'prettier/plugins/html'     // HTML
    import pluginPostcss  from 'prettier/plugins/postcss'  // CSS/SCSS/LESS
    import pluginMarkdown from 'prettier/plugins/markdown' // Markdown
    import parserYaml     from 'prettier/parser-yaml'          // YAML (若需)
    import parserXml     from '@prettier/plugin-xml'          // YAML (若需)
    import { minify as terserMinify } from 'terser'
    import { minify as htmlMinify } from 'html-minifier-terser'
    import { useWindow } from '../hooks/useWindow.ts'
    import { useDebounceEffect } from '../hooks/useDebounceEffect';
    import { useMenuStore } from '../stores/menuStore';
    import { BookOutline } from '@vicons/ionicons5';
    const menuStore = useMenuStore();
    const { createWebviewWindow } = useWindow()
    const appWindow = getCurrentWindow();
    const dialog = useDialog()
    const props = defineProps<{
      id: string
      title: string
      content: string
      type: string
      theme: string
      'onUpdate:moment'?: (id: string, content: string, title: string, openType: string) => any;
    }>()
    const emit = defineEmits(['update:moment'])
    let id = ref(props.id);
    let title = ref(props.title);
    const type = ref(props.type ?? "text");
    const searchText = ref(props.content)
    const searchText2 = ref('')
    const disabled = ref(false);
    const constModelData = ref([""]);
    const eheight = ref("height: calc(100vh);");
    const theme = ref(props.theme ?? "vs-dark");
    const editorConfig = ref({
        language: "sql",
        theme: props.theme ?? "vs-dark"
    });

    const message = useMessage()

    // 设置特殊页面的右键菜单项
    const onContextMenu = (event: MouseEvent) => {
      event.preventDefault();
      event.stopPropagation()
      // 特殊页面的右键菜单项
      const specialMenuItems = [
        { id: 'format', text: '格式化', action: async () => {
          await format()
        } },
        { id: 'newWindows', text: '新建窗口', action: async () => {
          await openEditor()
        } },
        { id: 'setLable', text: '设置title', action: async () => {
          dialog.warning({
            title: '设置title',
            closable: false,
            showIcon: false,
            content: () => h(NInput, {
              value: title.value,
              onUpdateValue: (value: string) => {
                title.value = value
              },
              placeholder: '请输入内容'
            }, {
              default: () => h(BookOutline)
            }),
            action: () => h(
              NButton,
              { text: true, 
                type: 'primary',
                onClick: async (e: Event) => {
                  e.stopPropagation()
                  dialog.destroyAll()
                  await appWindow.setTitle(title.value)
                }
              },
              { default: () => "保存" }
            )
          })
        } },
        { id: 'compress', text: '压缩', action: async () => {
          await compress()
        } },
        { id: 'escapeString', text: '转义', action: () => {
          escapeString()
        } },
        { id: 'unescapeString', text: '去转义', action: () => {
          unescapeString()
        } },
      ];
      if (type.value != 'md') {
        specialMenuItems.push(
          { id: 'md', text: 'md', action: async () => {
            type.value = 'md';
            await invoke("update_momento_content", { id: id.value, noteContent: searchText.value, title: title.value, openType: type.value});
          } }
        )
      }
      if (type.value != 'text') {
        specialMenuItems.push(
          { id: 'text', text: 'text', action: async () => {
            type.value = 'text';
            await invoke("update_momento_content", { id: id.value, noteContent: searchText.value, title: title.value, openType: type.value});
          } }
        )
      }
      if (type.value != 'diff') {
        specialMenuItems.push(
          { id: 'diff', text: '对比', action: async () => {
            type.value = 'diff';
            await invoke("update_momento_content", { id: id.value, noteContent: searchText.value, title: title.value, openType: type.value});
          } }
        )
      }
      menuStore.resetMenu(); // 重置当前菜单项
      menuStore.setMenu(specialMenuItems, { x: event.clientX, y: event.clientY });
    };

    // 监听 props 更新
    watch(() => props.type, (newType) => {
      type.value = newType;
    });

    // 监听其他 props 更新
    watch(() => props.content, (newContent) => {
      searchText.value = newContent;
    });

        // 监听其他 props 更新
    watch(() => props.id, (newId) => {
      id.value = newId;
    });
    const shouldSave = ref(false)

    onMounted(async () => {
        await appWindow.show();
        try {
          // 需要等待 DOM 更新
          nextTick(async () => {
              await appWindow.show();
              // 添加 50ms 延迟确保窗口完全渲染
              setTimeout(() => {
                  appWindow.setFocus() // 确保窗口获得焦点
                  setTimeout(() => {
                    shouldSave.value = true
                  }, 1000)
              }, 50)
          })
        } catch (error) {
            console.error('获取title：', error);
        }
    })

    // 把 invoke 的逻辑放到这里
    useDebounceEffect(searchText, async (_val) => {
      if (!shouldSave.value) return
      try {
        let data:any = await invoke("update_momento_content", { id: id.value, noteContent: searchText.value, title: title.value, openType: type.value});
        if (data.is_success) {
          
        }
        console.log('后台已更新')
      } catch (e) {
        console.error(`invoke 调用失败`, e)
      }
    }, 500)  // 800 ms 防抖


    // 监听 Ctrl + S 组合键
    useKeyboard('s', async (event) => {
        if (type.value === 'diff') {
            return
        }
        if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {
            event.preventDefault(); // 阻止默认保存行为（特别是在 Web 中）
            if (id.value) {
              try {
                let data:any = await invoke("update_momento_content", { id: id.value, noteContent: searchText.value, title: title.value, openType: type.value});
                if (data.is_success) {
                  message.success(
                      '更新成功'
                  )
                }
              } catch (e) {
                console.error(`invoke 调用失败`, e)
              }
            } else {
              if (searchText.value) {
                let data:any = await invoke("add_momento", {pid: "1", bookId: "1", noteContent: searchText.value, title: title.value, heading: title.value, isFolder: 0});
                if (data.is_success) {
                  id.value = data.data;
                  message.success(
                      '保存成功'
                  )
                }
              }
            }
        }
    });



    async function format() {
      if (searchText) {
        const code = searchText.value
        if (code) {
          const lang = detectByContent(code);
          const cfg = getPrettierConfig(lang)
          try {
            // 保留 monaco 换行（\n）风格
            const formatted = await prettier.format(code, {
              ...cfg,
              printWidth: 80,
              tabWidth: 2,
              htmlWhitespaceSensitivity: 'ignore',
              useTabs: false,
            })
            searchText.value = formatted
          } catch (err) {
            console.error('Prettier 格式化失败：', err)
          }
        }

      }

    }

    async function compress() {
    if (searchText) {

        const code = searchText.value;
        if (code) {
          const lang = detectByContent(code);
          try {
            if (lang === 'javascript') {
              const result = await terserMinify(code)
              searchText.value = result.code || ''
            } else if (lang === 'json') {
              const compressed = JSON.stringify(JSON.parse(code))
              searchText.value = compressed
            } else if (lang === 'html') {
              const compressed = htmlMinify(code, {
                collapseWhitespace: true,
                removeComments: true,
                minifyCSS: true,
                minifyJS: true,
              })
              searchText.value = compressed
            }
          } catch (e) {
            console.error('压缩失败', e)
          }
        }
      }

    }


    function escapeString() {
      let code = searchText.value;
      if (code) {
        searchText.value = code
          .replace(/\\/g, '\\\\')
          .replace(/\\b/g, '\\\\b')
          .replace(/"/g, '\\"')
          .replace(/'/g, "\\'")
          .replace(/\n/g, '\\n')
          .replace(/\r/g, '\\r')
          .replace(/\t/g, '\\t')
          .replace(/\f/g, '\\f')
      }
    }

    function unescapeString() {
      let code = searchText.value;
      if (code) {
        if (code.includes('\\\\')) {
          code = code.replace(/\\\\/g, '\\');
        } else {
          code = code
          .replace(/\\f/g, '\f')
          .replace(/\\b/g, '\b')
          .replace(/\\t/g, '\t')
          .replace(/\\r/g, '\r')
          .replace(/\\n/g, '\n')
          .replace(/\\"/g, '"')
          .replace(/\\'/g, "'");
        }
        searchText.value = code
      }
    }



    // 将 Monaco 语言映射到 Prettier parser + 插件
    function getPrettierConfig(lang: string) {
      switch (lang) {
        case 'javascript':
          return { parser: 'babel',      plugins: [pluginBabel, pluginEstree] }
        case 'typescript':
          return { parser: 'typescript', plugins: [pluginBabel, pluginEstree] }
        case 'json':
          return { parser: 'json',       plugins: [pluginBabel, pluginEstree] }
        case 'html':
          return { parser: 'html',       plugins: [pluginHtml] }
        case 'css':
          return { parser: 'css',        plugins: [pluginPostcss] }
        case 'markdown':
          return { parser: 'markdown',   plugins: [pluginMarkdown] }
        case 'yaml':
          return { parser: 'yaml', languages:'yaml',   plugins: [parserYaml] }
        case 'xml':
          return { parser: 'xml', languages:'xml',  plugins: [parserXml] }
        default:
          return { parser: 'babel',      plugins: [pluginBabel, pluginEstree] }
      }
    }


    function detectByContent(code: string): string {
      const t = code.trim();
      // HTML 优先，常用 html 标签
      if (/^<(!doctype|html|head|body|div|span|script|style|[a-z]+\s)/i.test(t))
        return 'html';
      // XML，要求有 <?xml 或自定义标签，并且排除 html 关键词
      if (
        /^<\?xml\s/.test(t) ||
        (/^<([a-zA-Z0-9]+)(\s|>)/.test(t) &&
          !/^<(html|head|body|div|span|script|style)/i.test(t))
      ) {
        return 'xml';
      }
      // JSON
      if (/^(?:\{[\s\S]*\}|\[[\s\S]*\])$/.test(t))
        return 'json';
      // YAML，且排除 < 开头
      if (!t.startsWith("<") && (/^---/.test(t) || /^[\w\-]+\s*:\s*.+/m.test(t))) {
        return 'yaml';
      }
      // Markdown
      if (/^#+\s+/m.test(t) || /\[[^\]]+\]\([^)]+\)/.test(t))
        return 'markdown';
      // SQL
      if (
        /\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|TRUNCATE|FROM|WHERE|JOIN)\b/i.test(t)
      ) {
        return 'sql';
      }
      // JavaScript
      if (/;\s*$/.test(t) || /\bfunction\b/.test(t))
        return 'javascript';
      // TypeScript
      if (/\:\s*string\b/.test(t) || /\binterface\b/.test(t))
        return 'typescript';
      // CSS
      if (/^[\w-]+\s*\{[\s\S]*\}/.test(t))
        return 'css';
      // fallback
      return 'javascript';
    }


    async function openEditor() {
      await createWebviewWindow('文本编辑-text', 'editor-'+new Date().getTime(), 'editor', 960, 720, undefined, true, undefined, 480, false, false);
    }

</script>

